/*
 * Copyright (c) 2020-2040, 北京符节科技有限公司 (support@fujieid.com & https://www.fujieid.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.fujieid.jap.oauth2;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.fujieid.jap.oauth2.pkce.PkceCodeChallengeMethod;
import org.jose4j.base64url.Base64Url;

/**
 * OAuth Strategy Util
 *
 * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
 * @version 1.0.0
 * @date 2021/1/14 15:38
 * @since 1.0.0
 */
public class Oauth2Util {

    /**
     * create code_verifier for pkce mode only.
     * <p>
     * high-entropy cryptographic random STRING using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
     * from <a href="https://tools.ietf.org/html/rfc3986#section-2.3" target="_blank">Section 2.3 of [RFC3986]</a>, with a minimum length of 43 characters and a maximum length of 128 characters.
     *
     * @return String
     * @see <a href="https://docs.fujieid.com/college/protocol/oauth-2.0/oauth-2.0-pkce" target="_blank">https://docs.fujieid.com/college/protocol/oauth-2.0/oauth-2.0-pkce</a>
     */
    public static String generateCodeVerifier() {
        return Base64Url.encode(RandomUtil.randomString(50), "UTF-8");
    }

    /**
     * Suitable for OAuth 2.0 pkce enhancement mode.
     *
     * @param codeChallengeMethod s256 / plain
     * @param codeVerifier        Generated by the client
     * @return code challenge
     * @see <a href="https://tools.ietf.org/html/rfc7636#section-4.2" target="_blank">https://tools.ietf.org/html/rfc7636#section-4.2</a>
     * @see <a href="https://docs.fujieid.com/college/protocol/oauth-2.0/oauth-2.0-pkce" target="_blank">https://docs.fujieid.com/college/protocol/oauth-2.0/oauth-2.0-pkce</a>
     */
    public static String generateCodeChallenge(PkceCodeChallengeMethod codeChallengeMethod, String codeVerifier) {
        if (PkceCodeChallengeMethod.S256 == codeChallengeMethod) {
            // https://tools.ietf.org/html/rfc7636#section-4.2
            // code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
            return Base64.encodeUrlSafe(SecureUtil.sha256().digest(codeVerifier));
        } else {
            return codeVerifier;
        }
    }
}
